package com.example.Redis6.Redis高级;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Set;

/**
 * 容量不够，redis如何进行扩容?
 * 并发写操作，redis如何分摊?
 *
 *
 * ➢什么是集群 //
 * ●Redis集群实现了对Redis的水平扩容,即启动N个redis节点，
 * 将整个数据份布存储在这N个节点中，每个节点存储总数据的1/N。
 * ●Redis集群通过分区(partition) 来提供一定程度的可用性(availability)
 * :即使集群中有一部分节点失效或者无法进行通讯，集群
 * 也可以继续处理命令请求。
 *
 * 1、安装ruby环境//低版本需要安装
 * 能上网:
 * 执行yum install ruby
 * 执行yum install rubygems
 *
 * vi 文件名//编辑文件
 * :%s/6379/6380   //把文件的6379全部改成6380
 * ●.创建多个配置文件//为了方便集群  大概内容如下
 *   redis6379.conf//文件名称   创三个  其三个名字
 *     include /myredis/redis.conf//表示在哪个配置文件上修改 引入配置文件
 *     pidfile "/var/run/redis_6379.pid"
 *     port 6379
 *     dbfilename "dump6379.rdb"//关闭AOF否则"还要"该AOF相关配置
 *     cluster-enabled yes//开启集群
 *     luster-config-file nodes-6379.conf//设置当前节点的名字
 *     cluster-node-timeout 15000//设置失联时间
 *启动成功标志：
 * nodes-6379.conf//此文件存在
 *
 * 先进入 redis-版本   这个文件中
 *    一般都是cd /opt     一般都装在了/opt下
 *     ls查看当前文件夹有哪些文件
 *     cd /redis-版本下的src
 *     cd /src
 * 在src文件下执行  redis-cli --cluster create --cluster-replicas 1
 *     //创建集群                  集群方式        1：最简单的方式创建集群（三主三从）
 *      192.168.11.101:6379//全部redis的ip和端口号   不能加127.0.0.1
 *      192.168.11.101:6380
 *      192.168.11.101:6381
 *      192.168.11.101:6389
 *      192.168.11.101:6390
 *      192.168.11.101:6391
 *
 * redis-cli -p 6379//进入redis
 * redis-cli -c -p 6379//以集群方式进入redis    任意一个端口号都可以进入
 *
 * 集群  里的Redis都要启动  但是只要执行一个  集群会给你自动配置
 * 他的主服务器信息有个插槽  [0-16383]   多主服务器自动分配
 *   每个存储信息   会算出一个插槽值   （集群使用CRC16（key））%16384  算出插槽值
 *   在某个插槽值范围内  存储在不同的主服务器中  他会切换到最近执行的主服务器
 *   三个的话   [0-5460]   [5461-10922]    [10923-16383]
 *
 *  客户端  代理   三个主节点//8台主机  三主三从+客户端+代理
 *  一个集群至少要有三个主节点。//无中心化集群  只要6台  三主三从
 * 选项一replicas 1表示我们希望为集群中的每个主节点创
 * 建一个从节点。
 * "分配原则"尽量保证每个主数据库运行在不同的IP地址，
 * 每个从库和主库不在一个IP地址上。
 *
 *
 * ➢在集群中录入值
 * 在redis-cli每次录入、查询键值, redis都会计算 出该key应该送往的
 * 插槽，如果不是该客户端对应服务器的插槽，redis会报错， 并告知
 * 应前往的redis实例地址和端口。
 * redis-cli客户端提供了C 参数实现"自动重定向"。
 * 如redis-cli -c -p 6379登入后，再录入、查询键值对可以自动重定向。
 * ● 不在一个slot 下的键值，是不能使用mget,mset等 多键操作。//获得 插入  多个键值
 * ● 可以通过{}来定义组的概念，从而使key中{}内相同内容的键值对放到-个slot中去。
 *       但可以定义组的概念   set key{组名} value//他的插槽根据组名计算
 */

/**
 * 集群操作
 * 每次操作   会进入插槽对应的redis中
 * cluster nodes//查看集群信息
 * cluster keyslot key//计算此key的插槽
 * cluster countkeysinslop 插槽大小//返回这个插槽有几个值  但只能查看自己redis对应的插槽的值
 * CLUSTER GETKEYSINSLOT <slot> <count> 返回count个slot槽的值中的键。
 *
 */

/**
 * 自动配置
 * 当某个主死后   从   上位一个   当主回来时   旧主变从
 * 当某个插槽值全死  即某个插槽范围   主从全死
 *     Redis服务停止   因为
 *     ●redis.conf中的参数cluster-require-full-coverage  yes/no
 *       ●16384个slot都正常的时候才能对外提供服务  yes
 *       ●只要操作的slot正常就对外提供服务  no
 * 让天下河办
 */

/**
 * Redis集群的好处
 *      实现扩容
 *      分摊压力
 *      无中心配置相对简单
 * Redis集群的不足:
 *      多键操作是不被支持的
 *      多键的Redis事务是不被支持的。lua脚本不被支持。
 *      由于集群方案出现较晚，很多公司已经采用了其他的集群方案，
 *          而代理或者客户端分片的方案想要迁移至redis cluster,
 *          需要整体迁移而不是逐步过渡，复杂度较大。
 */
public class Redis集群 {//解决内存压力

    public static void main(String[] args) {
        Set<HostAndPort> nodes = new HashSet<>();//存储 Redis信息
        nodes.add(new HostAndPort("127.0.0.1",6379));
        //但可以重定向  所以一个也行但必须同意从定向
        JedisCluster cluster = new JedisCluster(nodes);
        cluster.set("1","1");
        cluster.close();
    }

}
